package com.ruoyi.system.service.impl;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.modbus.Modbus4jWriteUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.domain.MrBed;
import com.ruoyi.system.domain.MrWard;
import com.ruoyi.system.mapper.MrBedMapper;
import com.ruoyi.system.service.IMrBedService;
import com.ruoyi.system.service.IMrWardService;
import com.ruoyi.system.service.ISysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 床位Service业务层处理
 *
 * @author ruoyi
 * @date 2023-04-01
 */
@Service
public class MrBedServiceImpl implements IMrBedService {
    @Autowired
    private MrBedMapper mrBedMapper;

    @Autowired
    private IMrWardService mrWardService;

    @Autowired
    private ISysConfigService configService;

    @PostConstruct
    public void init() {
        loadingBedCache();
    }

    @Override
    public void loadingBedCache() {
        MrBed bed = new MrBed();
        List<MrBed> beds = mrBedMapper.selectMrBedList(bed);
        Map<Integer, List<Integer>> deptWardCache = new HashMap<>();
        Map<Integer, List<Integer>> wardBesCache = new HashMap<>();
        beds.forEach(s -> {
            Integer deptId = Math.toIntExact(s.getDeptId());
            Integer wardId = Math.toIntExact(s.getWardId());
            Integer bedId = Math.toIntExact(s.getBedId());

            if (deptWardCache.containsKey(deptId)) {
                List<Integer> wardIds = deptWardCache.get(deptId);
                if (!wardIds.contains(wardId)) {
                    wardIds.add(wardId);
                }
                deptWardCache.put(deptId, wardIds);
            } else {
                deptWardCache.put(deptId, new ArrayList<>(Arrays.asList(wardId)));
            }

            if (wardBesCache.containsKey(wardId)) {
                List<Integer> bedIds = wardBesCache.get(wardId);
                if (!bedIds.contains(bedId)) {
                    bedIds.add(bedId);
                }
                wardBesCache.put(wardId, bedIds);
            } else {
                wardBesCache.put(wardId, new ArrayList<>(Arrays.asList(bedId)));
            }
            SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.BED_INFO_CACHE + s.getBedId(), s);
        });
        SpringUtils.getBean(RedisCache.class).setCacheObject("dept_ward_mapping", deptWardCache);
        SpringUtils.getBean(RedisCache.class).setCacheObject("ward_bed_mapping", wardBesCache);
    }

    /**
     * 查询床位
     *
     * @param bedId 床位主键
     * @return 床位
     */
    @Override
    public MrBed selectMrBedByBedId(Long bedId) {
        return mrBedMapper.selectMrBedByBedId(bedId);
    }

    /**
     * 查询床位列表
     *
     * @param mrBed 床位
     * @return 床位
     */
    @Override
    public List<MrBed> selectMrBedList(MrBed mrBed) {
        return mrBedMapper.selectMrBedList(mrBed);
    }

    /**
     * 新增床位
     *
     * @param mrBed 床位
     * @return 结果
     */
    @Override
    public int insertMrBed(MrBed mrBed) {
        mrBed.setCreateTime(DateUtils.getNowDate());
        int count = mrBedMapper.insertMrBed(mrBed);
        if (count > 0) {
            SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.BED_INFO_CACHE + mrBed.getBedId(), mrBed);

            MrWard mrWard = mrWardService.selectMrWardByWardId(mrBed.getWardId());
            if (mrWard != null && !mrWard.getFloor().isEmpty()) {
                String port = configService.selectConfigByKey(Constants.CONFIGURATION_PORT);
                port = port == null ? "9999" : port;
                try {
                    Modbus4jWriteUtils.writeCoil(mrWard.getFloor(), Integer.parseInt(port), 1, 1, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return count;
    }

    /**
     * 修改床位
     *
     * @param mrBed 床位
     * @return 结果
     */
    @Override
    public int updateMrBed(MrBed mrBed) {
        mrBed.setUpdateTime(DateUtils.getNowDate());
        int count = mrBedMapper.updateMrBed(mrBed);
        if (count > 0) {
            SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.BED_INFO_CACHE + mrBed.getBedId(), mrBed);

            MrWard mrWard = mrWardService.selectMrWardByWardId(mrBed.getWardId());
            if (mrWard != null && !mrWard.getFloor().isEmpty()) {
                String port = configService.selectConfigByKey(Constants.CONFIGURATION_PORT);
                port = port == null ? "9999" : port;
                try {
                    Modbus4jWriteUtils.writeCoil(mrWard.getFloor(), Integer.parseInt(port), 1, 1, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        return count;
    }

    /**
     * 批量删除床位
     *
     * @param bedIds 需要删除的床位主键
     * @return 结果
     */
    @Override
    public int deleteMrBedByBedIds(Long[] bedIds) {
        int count = mrBedMapper.deleteMrBedByBedIds(bedIds);
        if (count > 0) {
            for (Long bedId : bedIds) {
                SpringUtils.getBean(RedisCache.class).deleteObject(CacheConstants.BED_INFO_CACHE + bedId);
            }
        }
        return count;
    }

    /**
     * 删除床位信息
     *
     * @param bedId 床位主键
     * @return 结果
     */
    @Override
    public int deleteMrBedByBedId(Long bedId) {
        int count = mrBedMapper.deleteMrBedByBedId(bedId);
        if (count > 0) {
            SpringUtils.getBean(RedisCache.class).deleteObject(CacheConstants.BED_INFO_CACHE + bedId);
        }
        return count;
    }

    @Override
    public int checkWardBandBed(Long[] wardIds) {
        return mrBedMapper.checkWardBandBed(wardIds);
    }

    @Override
    public List<MrBed> selectMrBedByDevSn(String devSn) {
        return mrBedMapper.selectMrBedByDevSn(devSn);
    }
}
